package wiki.hitime.stl.daq.manager;

import com.alibaba.fastjson.JSON;
import wiki.hitime.stl.daq.bean.db.DaqAcquisitionRule;
import wiki.hitime.stl.daq.bean.db.DaqAcquisitionRuleHistory;
import wiki.hitime.stl.daq.bean.dto.manage.AcquisitionRuleDTO;
import wiki.hitime.stl.daq.bean.dto.req.AcquisitionRuleGetReqDTO;
import wiki.hitime.stl.daq.bean.dto.req.AcquisitionRuleUpdateReqDTO;
import wiki.hitime.stl.daq.enums.OperateActionEnum;
import wiki.hitime.stl.daq.exception.ServiceException;
import wiki.hitime.stl.daq.mapper.DaqAcquisitionRuleHistoryMapper;
import wiki.hitime.stl.daq.mapper.DaqAcquisitionRuleMapper;
import wiki.hitime.stl.daq.util.UserContextUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import tk.mybatis.mapper.entity.Example;

/**
 * @author zhangdaoping
 * @create 2019-07-17 09:49
 */
@Service
public class DaqAcquisitionRuleManager {

    private DaqAcquisitionRuleMapper daqAcquisitionRuleMapper;
    private DaqAcquisitionRuleHistoryMapper daqAcquisitionRuleHistoryMapper;

    public DaqAcquisitionRuleManager(DaqAcquisitionRuleMapper daqAcquisitionRuleMapper,
                                     DaqAcquisitionRuleHistoryMapper daqAcquisitionRuleHistoryMapper) {
        this.daqAcquisitionRuleMapper = daqAcquisitionRuleMapper;
        this.daqAcquisitionRuleHistoryMapper = daqAcquisitionRuleHistoryMapper;
    }

    /**
     * 获取规则
     *
     * @param executeRuleId
     * @return
     */
    public DaqAcquisitionRule getByExecuteRuleId(Long executeRuleId) {
        Example selectExample = new Example(DaqAcquisitionRule.class, true, true);
        selectExample.createCriteria().andEqualTo("executeRuleId", executeRuleId).andEqualTo("isDelete", Boolean.FALSE);
        return daqAcquisitionRuleMapper.selectOneByExample(selectExample);
    }

    /**
     * 获取规则
     *
     * @param id
     * @return
     */
    public DaqAcquisitionRule getById(Long id) {
        Example selectExample = new Example(DaqAcquisitionRule.class, true, true);
        selectExample.createCriteria().andEqualTo("id", id).andEqualTo("isDelete", Boolean.FALSE);
        return daqAcquisitionRuleMapper.selectOneByExample(selectExample);
    }

    /**
     * 添加规则
     *
     * @param acquisitionRuleDTO 规则DTO
     * @return
     */
    public Long add(AcquisitionRuleDTO acquisitionRuleDTO) {
        DaqAcquisitionRule daqAcquisitionRule = DaqAcquisitionRule.builder()
                .executeRuleId(acquisitionRuleDTO.getExecuteRuleId())
                .ruleName(acquisitionRuleDTO.getRuleName())
                .acquisitionExpression(acquisitionRuleDTO.getAcquisitionExpression())
                .dbConfigId(acquisitionRuleDTO.getDbConfigId())
                .acquisitionType(acquisitionRuleDTO.getAcquisitionType())
                .valueType(acquisitionRuleDTO.getValueType())
                .valueFormat(acquisitionRuleDTO.getValueFormat())
                .remark(acquisitionRuleDTO.getRemark())
                .ctlVersion(1L)
                .createdUserId(UserContextUtil.getJobNumber())
                .createdUser(UserContextUtil.getTrueName())
                .modifiedUserId(UserContextUtil.getJobNumber())
                .modifiedUser(UserContextUtil.getTrueName())
                .build();
        daqAcquisitionRuleMapper.insertSelective(daqAcquisitionRule);
        Long id = daqAcquisitionRule.getId();
        this.addHistory(id);
        return id;
    }

    private void addHistory(Long ruleId) {
        DaqAcquisitionRuleHistory daqAcquisitionRuleHistory = new DaqAcquisitionRuleHistory();
        DaqAcquisitionRule daqAcquisitionRule = daqAcquisitionRuleMapper.selectByPrimaryKey(ruleId);
        BeanUtils.copyProperties(daqAcquisitionRule, daqAcquisitionRuleHistory);
        daqAcquisitionRuleHistory.setRuleId(daqAcquisitionRule.getId());
        OperateActionEnum operateActionEnum = daqAcquisitionRule.getCtlVersion() == 1 ? OperateActionEnum.ADD : OperateActionEnum.UPDATE;
        operateActionEnum = Boolean.TRUE.equals(daqAcquisitionRule.getIsDelete()) ? OperateActionEnum.DELETE : operateActionEnum;
        daqAcquisitionRuleHistory.setOperateAction(operateActionEnum.getStatus());
        daqAcquisitionRuleHistory.setOperateData(JSON.toJSONString(daqAcquisitionRule));
        daqAcquisitionRuleHistoryMapper.insertSelective(daqAcquisitionRuleHistory);
    }

    /**
     * 获取DTO
     *
     * @param reqDTO 请求实体
     * @return
     */
    public AcquisitionRuleDTO getDTO(AcquisitionRuleGetReqDTO reqDTO) {
        Example example = new Example(DaqAcquisitionRule.class, true, true);
        example.createCriteria().andEqualTo("isDelete", Boolean.FALSE);
        Example.Criteria orCriteria = example.createCriteria();
        if (reqDTO.getId() != null) {
            orCriteria.orEqualTo("id", reqDTO.getId());
        }
        if (reqDTO.getExecuteRuleId() != null) {
            orCriteria.orEqualTo("executeRuleId", reqDTO.getExecuteRuleId());
        }
        example.and(orCriteria);
        return convertDTO(daqAcquisitionRuleMapper.selectOneByExample(example));
    }

    private AcquisitionRuleDTO convertDTO(DaqAcquisitionRule daqAcquisitionRule) {
        if (daqAcquisitionRule == null) {
            return null;
        }
        AcquisitionRuleDTO acquisitionRuleDTO = new AcquisitionRuleDTO();
        BeanUtils.copyProperties(daqAcquisitionRule, acquisitionRuleDTO);
        return acquisitionRuleDTO;
    }

    /**
     * 修改规则
     *
     * @param reqDTO 请求实体
     * @return 修改结果，true-成功，false-失败
     */
    public Boolean updateRule(AcquisitionRuleUpdateReqDTO reqDTO) throws ServiceException {
        AcquisitionRuleDTO ruleDTO = reqDTO.getAcquisitionRuleDTO();
        DaqAcquisitionRule daqRule = daqAcquisitionRuleMapper.selectByPrimaryKey(ruleDTO.getId());
        if (daqRule == null) {
            throw new ServiceException("未查到待修改的采集规则");
        }
        BeanUtils.copyProperties(ruleDTO, daqRule);
        return this.updateRule(daqRule);
    }

    private Boolean updateRule(DaqAcquisitionRule daqRule) {
        daqRule.setCtlVersion(daqRule.getCtlVersion() + 1);
        daqRule.setModifiedUserId(UserContextUtil.getJobNumber());
        daqRule.setModifiedUser(UserContextUtil.getTrueName());
        Example updateExample = new Example(DaqAcquisitionRule.class, true, true);
        updateExample.createCriteria().andEqualTo("id", daqRule.getId()).andEqualTo("ctlVersion", daqRule.getCtlVersion() - 1);
        int count = daqAcquisitionRuleMapper.updateByExampleSelective(daqRule, updateExample);
        if (count == 1) {
            this.addHistory(daqRule.getId());
        }
        return count == 1;
    }

    /**
     * 逻辑删除规则
     *
     * @param executeRuleId
     */
    public void delete(Long executeRuleId) {
        Example selectExample = new Example(DaqAcquisitionRule.class, true, true);
        selectExample.createCriteria().andEqualTo("executeRuleId", executeRuleId).andEqualTo("isDelete", Boolean.FALSE);
        DaqAcquisitionRule rule = daqAcquisitionRuleMapper.selectOneByExample(selectExample);
        Assert.notNull(rule, "采集规则为空");
        rule.setIsDelete(Boolean.TRUE);
        this.updateRule(rule);
    }
}
